//
// Author    : Pablo Bosch 
// Contact   : pboschvivancos@epo.org
// Created   : 08/05/2008
// Last Modif: 09/03/2009
//


/*----------------------------------------------------*/
/* Complex functions dealing with changes in features */
/*----------------------------------------------------*/

function featuresplit(cl,tf,txt1,txt2,pn){
  SetFeatureDesc(cl,tf,txt2);
  //alert("replace "+cl+","+tf+" "+txt2);
  InsertFeatureBefore(cl,tf,txt1);
  //alert("insert before "+cl+","+tf+" "+txt1);
 
  var checkcls=new List();   
  var cl_iter= new claim_iterator();
  // fix references to cl.tf   
  while(!cl_iter.end()) {
    var tf_iter= new claim_features_iterator(cl_iter.getValue());
    while(!tf_iter.end()) { 
      var teq=tf_iter.getEq();
      if(teq) {
	var cltf= new claim_tf(teq);
	if(cltf.getcl()==cl) {
	  if(cltf.gettf() > tf) { // if points after tf, shift downwards
	    cltf.settf((1*cltf.gettf())+1);
	    tf_iter.setEq(cltf.getValue());
	    checkcls.push(tf_iter.gettext());
	  } else if(cltf.gettf()==tf) { // if point exactly to tf, ask user
            // mark feature warning	    
	    SetFeatureWarn(tf_iter.getcl(),tf_iter.gettf(),"Splitted "+cl+"."+tf); 	    
	    checkcls.push(tf_iter.gettext());	    
	  } 
	}
      }
      tf_iter.next();
    }
    cl_iter.next();
  }
  // put glue for other docs 
  if(pn) {
    if(pn=="clarity") { // put glue everywhere
      var doc_iter= new doc_iterator();
      while(!doc_iter.end()) { 
	SetPassageHint(cl,tf,doc_iter.getPN(), GLUE_HINT);          
	doc_iter.next();
      } 
    } else { // put glue on other docs that had already a citation
      var doc_iter= new doc_iterator();
      while(!doc_iter.end()) { 
	if(doc_iter.getPN()!=pn) {
	  if(GetPassageHintEq(cl,1+tf,doc_iter.getPN()) || GetPassageReferenceEq(cl,1+tf,doc_iter.getPN())){
	    SetPassageHint(cl,tf,doc_iter.getPN(), GLUE_HINT);
	  }
	}
	doc_iter.next();
      } 
    }
  }
  
  // for all features below 
  featureupdatevalfromautoall(cl,tf,GetFeaturesLength(cl));
  return checkcls;
}

function featuresjoin(cl,tf) {
  //alert("Join "+tf+" and "+(tf-1));
  SetFeatureDesc(cl,tf-1,GetFeatureDesc(cl,tf-1)+" "+GetFeatureDesc(cl,tf));    
  SetFeatureUnclarity(cl,tf-1,GetFeatureUnclarity(cl,tf-1) || GetFeatureUnclarity(cl,tf));
  var doc_iter= new doc_iterator();
  while(!doc_iter.end()) {
     SetPassageHint(cl,tf-1,doc_iter.getPN(),hint_join(GetPassageHint(cl,tf-1,doc_iter.getPN()),
						      GetPassageHint(cl,tf,doc_iter.getPN())));
    
    

    if(GetPassageReference(cl,tf-1,doc_iter.getPN()) && GetPassageReference(cl,tf,doc_iter.getPN())) {
      SetPassageReference(cl,tf-1,doc_iter.getPN(),
			  GetPassageReference(cl,tf-1,doc_iter.getPN())
			  +" ; "
			  +GetPassageReference(cl,tf,doc_iter.getPN()));
    } else if(GetPassageReference(cl,tf,doc_iter.getPN())){
      SetPassageReference(cl,tf-1,doc_iter.getPN(),GetPassageReference(cl,tf,doc_iter.getPN()));
    }  
    
    doc_iter.next();
  }
  DeleteFeature(cl,tf);
  // fix references to cl.tf , changes to the tf itself are not handled automatically but prompted to user
  var checkcls=new List();
  var cl_iter = new claim_iterator();
  var ntfs=GetFeaturesLength(cl);


  while(!cl_iter.end()) { 
    var tf_iter= new claim_features_iterator(cl_iter.getValue());
    while(!tf_iter.end()) { 
      var teq=tf_iter.getEq();
      if(teq) {
	var cltf= new claim_tf(teq);
	if(cltf.getcl()==cl) { // points to claim cl
	  var _tf=cltf.gettf();
	  if(_tf>tf || _tf>ntfs) {
            cltf.settf(_tf-1);
	    tf_iter.setEq(cltf.getValue());
	    checkcls.push(tf_iter.gettext());
	  } else if(_tf==tf) {
	    // mark feature warning
            SetFeatureWarn(tf_iter.getcl(),tf_iter.gettf(),"Joined "+cl+"."+tf); 
	    checkcls.push(tf_iter.gettext());
	  } 
	}
      }
      tf_iter.next();
    }
    cl_iter.next();
  }
  // for all features below, update forall docs   
  featureupdatevalfromautoall(cl,tf-1,ntfs-1);
  return checkcls;
}

function featurechangeeq(cl,tf,val) {
  if(val) {
    var eqtf=new claim_vtf(val);    
    // check if val is OK
    if(eqtf.getver() !=GetClaimSetVersion()) {
      alert("Cannot set equivalence between features of different sets");
      return false;
    }
    // clear vers info
    eqtf.setver("");
    if(!is_claim_tf(eqtf.getcl(),eqtf.gettf())) {
      alert("Technical feature TF "+eqtf.getcl()+"."+(eqtf.gettf()||"")+" does not exist!"); 
      return false;
    } 
    // check if val is not already pointing to someone else 
    var tfeq=GetFeatureEq(eqtf.getcl(),eqtf.gettf());
    if(tfeq) { // do not allow tfeq of a tfeq
      alert("Cannot set feature "+cl+"."+tf+" equivalent to "+val+" because "+
	    val+" is equivalent to "+tfeq); 
      return false;
    }
    
    // check if no one is pointing to me (cl)    
    var eq_iter= new EqTF_claim_iterator(cl,tf);
    if(!eq_iter.end()) {
      alert("Cannot set feature "+cl+"."+tf+" equivalent to "+val+" because "+
	    eq_iter.getValue()+"  has features eq to  "+cl+"."+tf);
      return false;
    }
    // Ok , let's do it 
    SetFeatureEq(cl,tf,eqtf.getValue());

    // Update clarity objections     
    featureupdateclarity(cl,tf,GetFeatureUnclarity(eqtf.getcl(),eqtf.gettf()));
    
    if(!GetClaimEq(cl)) {
      // maybe has to reevaluate B
      if(GetClaimDoc_X(cl)) {    
	featureupdatehints(cl,tf,GetClaimDoc_X(cl),GetPassageHint(eqtf.getcl(),eqtf.gettf(),GetClaimDoc_X(cl)));
      }
    }  
  
    
  } else {
    SetFeatureEq(cl,tf,""); 
    featureupdateclarity(cl,tf,GetFeatureUnclarity(cl,tf));
    // maybe has to reevaluate B
    if(!GetClaimEq(cl)) {      
      if(GetClaimDoc_X(cl)) {
	featureupdatehints(cl,tf,GetClaimDoc_X(cl),GetPassageHint(cl,tf,GetClaimDoc_X(cl)));
      }
    }
  }
  // eq may change auto val
  featureupdatevalfromautoall(cl,tf);

  return true;
}


function featureupdatehints(cl,tf,pn,newhintval,mincl) {
  if(GetPassageHint(cl,tf,pn)!=newhintval) {
    new_Taint(cl);
    SetPassageHint(cl,tf,pn,newhintval);    
    // hint may change auto val
    featureupdatevalfromauto(cl,tf,pn);
    // a hint may change from novel to inventive so we have to recalculate B and strategies 
    var cl_iter= new claim_iterator(mincl || cl);  
    while(!cl_iter.end()) {
      if(GetClaimDoc_X(cl_iter.getValue()) == pn) {
	update_B_hints(cl_iter.getValue(),pn);   
      }
      updatefromdocs(cl_iter.getValue());
      cl_iter.next();
    }
  }
}  

function featureupdateclarity(cl,tf,clar) {
  var eq="";
  if(tf) {
    if(!GetFeatureEq(cl,tf)) {
      SetFeatureUnclarity(cl,tf,clar);
    }  
  }
  var tf_iter= new claim_features_iterator(cl);
  while(!tf_iter.end()) { 
    if(GetFeatureUnclarityEq(tf_iter.getcl(),tf_iter.gettf())) {
      SetClaimUnclear(cl);
      return;
    }
    tf_iter.next();
  }

  SetClaimClear(cl);
}

function featureupdatepassage(cl,tf,pn,txt) {
  SetPassageReference(cl,tf,pn,NormalizeCitation(txt));
  featureupdatevalfromauto(cl,tf,pn);
  // hint may change auto val
}


function featurechangeimp(cl,tf,txt) {
  //alert("tfonchangetfimp("+cl+","+tf+","+txt+")")
  if(!txt) {    
    if(confirm("Do you want to delete all passages for technical feature "+cl+"."+tf+" ?")) {
      ImportPassages(cl,tf);
    }
  } else {
    var imp = new claim_vtf(txt);    
    if(!imp.getver()) {
      imp.setver(MOD_CTF.tfimpver);
    }
    ImportPassages(cl,tf,imp.getver(),imp.getcl(),imp.gettf());
  }
  featurechangeeq(cl,tf,GetFeatureEq(cl,tf));
  featureupdatevalfromautoall(cl,tf);
  return true;
}

// returns list of modified claims
function featureupdatevalfromauto(cl,tf,pn){
  UpdateClaimAutoVal(cl,pn);    
  var eq_iter= new EqTF_claim_iterator(cl,tf);
  while(!eq_iter.end()) {
    UpdateClaimAutoVal(eq_iter.getValue(),pn);
    eq_iter.next();
  }
}

function featureupdatevalfromautoall(cl,tf1,tf2) {
  var clist= new List(cl);
  if(!tf2) {
    tf2=tf1;
  }
  while(tf1<=tf2) {
    //alert("Check "+cl+"."+tf1);
    var eq_iter= new EqTF_claim_iterator(cl,tf1);
    while(!eq_iter.end()) {
      clist.push(eq_iter.getValue());
      eq_iter.next();
    }
    tf1++;
  }
  var cl_iter=clist.reduce().iterator();
  while(!cl_iter.end()) {
    var doc_iter= new doc_iterator(); 
    while(!doc_iter.end()) {
      //alert("featureupdate "+cl_iter.getValue()+" "+doc_iter.getPN()+" is "+ClaimAutoVal(cl_iter.getValue(),doc_iter.getPN()));
      SetClaimDocAutoVal(cl_iter.getValue(),doc_iter.getPN(),ClaimAutoVal(cl_iter.getValue(),doc_iter.getPN()));
      //set_Tainted(cl_iter.getValue());
      doc_iter.next();
    } 
    cl_iter.next();
  }
}
